package com.xyzwps.example.stream;

import java.util.HashSet;

public class UniqueOperator<T> implements Operator<T, T> {

    private final HashSet<T> set;

    public UniqueOperator() {
        this.set = new HashSet<>();
    }

    @Override
    public Stream<T> handle(Stream<T> origin) {
        return new Stream<>() {
            @Override
            public Parcel<T> next() {
                while (true) {
                    var parcel = origin.next();
                    switch (parcel) {
                        case Parcel.Done<T> ignored -> {
                            return Parcel.done();
                        }
                        case Parcel.Failure<T> failure -> {
                            return Parcel.failed(failure.cause());
                        }
                        case Parcel.Delivery<T> delivery -> {
                            var t = delivery.value();
                            if (!set.contains(t)) {
                                set.add(t);
                                return Parcel.deliver(t);
                            }
                        }
                    }
                }
            }
        };
    }
}
